#pragma once

// Conversion from RGB to YUV420
static int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256];
static int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256];
static int RGB2YUV_VG[256], RGB2YUV_VB[256];

// Conversion from YUV420 to RGB24
static long int crv_tab[256];
static long int cbu_tab[256];
static long int cgu_tab[256];
static long int cgv_tab[256];
static long int tab_76309[256];
static unsigned char clp[1024];   //for clip in CCIR601


//
// Table used for RGB to YUV420 conversion
//
static void InitLookupTable()
{
	int i;

	for (i = 0; i < 256; i++) RGB2YUV_YR[i] = (float)65.481 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_YG[i] = (float)128.553 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_YB[i] = (float)24.966 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_UR[i] = (float)37.797 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_UG[i] = (float)74.203 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_VG[i] = (float)93.786 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_VB[i] = (float)18.214 * (i<<8);
	for (i = 0; i < 256; i++) RGB2YUV_UBVR[i] = (float)112 * (i<<8);
}


//
//  Convert from  RGB24 to YUV420
//
static int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned int *yuv)
{

	unsigned int *u,*v,*y,*uu,*vv;
	unsigned int *pu1,*pu2,*pu3,*pu4;
	unsigned int *pv1,*pv2,*pv3,*pv4;
	unsigned char *r,*g,*b;
	int i,j;

	uu=new unsigned int[w*h];
	vv=new unsigned int[w*h];

	if(uu==NULL || vv==NULL)
		return 0;

	y=yuv;
	u=uu;
	v=vv;

	// Get r,g,b pointers from bmp image data....
	r=bmp;
	g=bmp+1;
	b=bmp+2;


	//Get YUV values for rgb values...
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			*y++=( RGB2YUV_YR[*r]  +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;
			*u++=(-RGB2YUV_UR[*r]  -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16;
			*v++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
			r+=3;
			g+=3;
			b+=3;
		}
	}



	// Now sample the U & V to obtain YUV 4:2:0 format

	// Sampling mechanism...
	/*   @  ->  Y
	#  ->  U or V

	@   @   @   @
	#       #
	@   @   @   @

	@   @   @   @
	#       #
	@   @   @   @

	*/

	// Get the right pointers...
	u=yuv+w*h;
	v=u+(w*h)/4;

	// For U
	pu1=uu;
	pu2=pu1+1;
	pu3=pu1+w;
	pu4=pu3+1;

	// For V
	pv1=vv;
	pv2=pv1+1;
	pv3=pv1+w;
	pv4=pv3+1;

	// Do sampling....
	for(i=0;i<h;i+=2)
	{
		for(j=0;j<w;j+=2)
		{
			*u++=(*pu1+*pu2+*pu3+*pu4)>>2;
			*v++=(*pv1+*pv2+*pv3+*pv4)>>2;

			pu1+=2;
			pu2+=2;
			pu3+=2;
			pu4+=2;

			pv1+=2;
			pv2+=2;
			pv3+=2;
			pv4+=2;
		}

		pu1+=w;
		pu2+=w;
		pu3+=w;
		pu4+=w;

		pv1+=w;
		pv2+=w;
		pv3+=w;
		pv4+=w;
	}

	delete uu;
	delete vv;
	return 1;
}

 

 

 

//
//Initialize conversion table for YUV420 to RGB
//
static void InitConvertTable()
{
	long int crv,cbu,cgu,cgv;
	int i,ind;   

	crv = 104597; cbu = 132201;  /* fra matrise i global.h */
	cgu = 25675;  cgv = 53279;

	for (i = 0; i < 256; i++) 
	{
		crv_tab[i] = (i-128) * crv;
		cbu_tab[i] = (i-128) * cbu;
		cgu_tab[i] = (i-128) * cgu;
		cgv_tab[i] = (i-128) * cgv;
		tab_76309[i] = 76309*(i-16);
	}

	for (i=0; i<384; i++)
	{
		clp[i] =0;
	}
	ind=384;
	for (i=0;i<256; i++)
	{
		clp[ind++]=i;
	}
	ind=640;
	for (i=0;i<384;i++)
	{
		clp[ind++]=255;
	}
}


//
//  Convert from YUV420 to RGB24
//
static void ConvertYUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,
         int width,int height)
{
	int y1,y2,u,v; 
	unsigned char *py1,*py2;
	int i,j, c1, c2, c3, c4;
	unsigned char *d1, *d2;

	py1=src0;
	py2=py1+width;
	d1=dst_ori;
	d2=d1+3*width;
	for (j = 0; j < height; j += 2) 
	{ 
		for (i = 0; i < width; i += 2)
		{
			u = *src1++;
			v = *src2++;

			c1 = crv_tab[v];
			c2 = cgu_tab[u];
			c3 = cgv_tab[v];
			c4 = cbu_tab[u];

			//up-left
			y1 = tab_76309[*py1++]; 
			*d1++ = clp[384+((y1 + c1)>>16)];  
			*d1++ = clp[384+((y1 - c2 - c3)>>16)];
			*d1++ = clp[384+((y1 + c4)>>16)];

			//down-left
			y2 = tab_76309[*py2++];
			*d2++ = clp[384+((y2 + c1)>>16)];  
			*d2++ = clp[384+((y2 - c2 - c3)>>16)];
			*d2++ = clp[384+((y2 + c4)>>16)];

			//up-right
			y1 = tab_76309[*py1++];
			*d1++ = clp[384+((y1 + c1)>>16)];  
			*d1++ = clp[384+((y1 - c2 - c3)>>16)];
			*d1++ = clp[384+((y1 + c4)>>16)];

			//down-right
			y2 = tab_76309[*py2++];
			*d2++ = clp[384+((y2 + c1)>>16)];  
			*d2++ = clp[384+((y2 - c2 - c3)>>16)];
			*d2++ = clp[384+((y2 + c4)>>16)];
		}
		d1 += 3*width;
		d2 += 3*width;
		py1+=   width;
		py2+=   width;
	}
}

